﻿#include "validator.h"

#include <QLineEdit>

namespace flow
{
DoubleValidator::DoubleValidator(double bottom, double top, int decimals, bool fixFieldWidth, QObject* parent)
    : QDoubleValidator(bottom, top, decimals, parent), _decimals(decimals)
    , _fixFieldWidth(fixFieldWidth)
{
    if (parent && _fixFieldWidth) {
        if (auto edit = dynamic_cast<QLineEdit*>(parent)) {
            connect(edit, &QLineEdit::editingFinished, this, [this, edit] {
                edit->blockSignals(true);
                QString text = edit->text();
                this->fixup(text);
                edit->setText(text);
                edit->blockSignals(false);
            });
        }
    }
}

QValidator::State DoubleValidator::validate(QString& input, int& pos) const
{
    if (input.isEmpty()) {
        return QValidator::Intermediate;
    }
    bool isOK = false;
    if (input.length() == 1 && input.at(0) == '-' && bottom() < 0) {
        return QValidator::Acceptable;
    }
    const double value = input.toDouble(&isOK);
    if (!isOK) {
        return QValidator::Invalid;
    }
    const int dotPos = input.indexOf(".");
    if (dotPos > 0) {
        if (input.right(input.length() - (dotPos + 1)).length() > decimals()) {
            return QValidator::Invalid;
        }
    }
    if (value >= bottom() && value <= top()) {
        return QValidator::Acceptable;
    }

    return QValidator::Intermediate;
}

void DoubleValidator::fixup(QString& input) const
{
    const double inputValue = input.toDouble();

    // 如果输入的值大于上限，则设置为上限
    if (inputValue > top()) {
        input = QString::number(top(), 'f', _decimals);
    }
    // 如果输入的值小于下限或输入的内容为空，则设置为下限
    else if (inputValue < bottom() || input.trimmed().isEmpty()) {
        input = QString::number(bottom(), 'f', _decimals);
    }
    // 如果输入在有效范围内，则按照有效位数显示
    else if (_fixFieldWidth) {
        input = QString::number(inputValue, 'f', _decimals);
    }
}

// QValidator::State IntValidator::validate(QString &input, int &pos) const {
//  return QValidator::validate(input,pos);
// }

void IntValidator::fixup(QString& input) const
{
    if (input.toInt() > top()) {
        input = QString::number(top());
    }
    else if (input.toInt() < bottom() || input.trimmed().isEmpty()) {
        input = QString::number(bottom());
    }
}
} // namespace cq
